/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

//import * as path from 'path';
// import * as fs from 'original-fs';
// import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { writeFileAndFlushSync } from 'vs/base/node/extfs';
import { isUndefined, isUndefinedOrNull } from 'vs/base/common/types';
import { IStateService } from 'vs/platform/state/common/state';
// import { ILogService } from 'vs/platform/log/common/log';

export class FileStorage {

	private database: object = null;

	constructor(private dbPath: string, private onError: (error) => void) { }

	private ensureLoaded(): void {
		if (!this.database) {
			this.database = this.loadSync();
		}
	}

	public getItem<T>(key: string, defaultValue?: T): T {
		this.ensureLoaded();

		const res = this.database[key];
		if (isUndefinedOrNull(res)) {
			return defaultValue;
		}

		return res;
	}

	public setItem(key: string, data: any): void {
		this.ensureLoaded();

		// Remove an item when it is undefined or null
		if (isUndefinedOrNull(data)) {
			return this.removeItem(key);
		}

		// Shortcut for primitives that did not change
		if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {
			if (this.database[key] === data) {
				return;
			}
		}

		this.database[key] = data;
		this.saveSync();
	}

	public removeItem(key: string): void {
		this.ensureLoaded();

		// Only update if the key is actually present (not undefined)
		if (!isUndefined(this.database[key])) {
			this.database[key] = void 0;
			this.saveSync();
		}
	}

	private loadSync(): object {
		throw new Error("不支持");
		// try {
		// 	return JSON.parse(fs.readFileSync(this.dbPath).toString()); // invalid JSON or permission issue can happen here
		// } catch (error) {
		// 	if (error && error.code !== 'ENOENT') {
		// 		this.onError(error);
		// 	}

		// 	return {};
		// }
	}

	private saveSync(): void {
		try {
			writeFileAndFlushSync(this.dbPath, JSON.stringify(this.database, null, 4)); // permission issue can happen here
		} catch (error) {
			this.onError(error);
		}
	}
}

export class StateService implements IStateService {

	_serviceBrand: any;

	constructor() {
		this._serviceBrand = {};
	}

	public getItem<T>(key: string, defaultValue?: T): T {
		if (this._serviceBrand[key]) {
			return this._serviceBrand[key];
		}
		return defaultValue;
	}

	public setItem(key: string, data: any): void {
		this._serviceBrand[key] = data;
	}

	public removeItem(key: string): void {
		delete this._serviceBrand[key];
	}
}
